<?php
/* --------------------------------------------------------------
   GMSitemapXML.php 2011-09-27 gambio
   Gambio GmbH
   http://www.gambio.de
   Copyright (c) 2011 Gambio GmbH
   Released under the GNU General Public License (Version 2)
   [http://www.gnu.org/licenses/gpl-2.0.html]
   --------------------------------------------------------------
*/
?><?php

	/*
	*	-> class to create a google sitemap
	*/
	class GMSitemapXML 
	{		
		/*
		*	-> category path
		*/
		var $coo_cat_path;

		/*
		*	-> category sub path
		*/
		var $coo_cat_sub_path;

		/*
		*	-> language_id
		*/
		var $coo_language_id;

		/*
		*	-> default changefreq
		*/
		var $coo_changefreq;

		/*
		*	-> default priority
		*/
		var $coo_priority;
		
		/*
		*	-> to count generated links
		*/
		var $coo_link_counter;

		/*
		*	-> request uri
		*/
		var $coo_request_uri;

		/*
		*	-> object for SEF Urls
		*/
		var $coo_seo_boost;

		/*
		*	-> array of search engines to ping
		*/
		var $coo_ping = array();

		/*
		*	-> kind of xml encoding - e.g. 'UTF-8', 'ISO-8859-1', etc.
		*/
		var $coo_xml_encoding		= 'UTF-8';


		/*
		*	-> kind of the xml version
		*/
		var $coo_xml_version		= '1.0';		
		

		/*
		*	-> references the current protocol standard
		*/
		var $coo_path				= DIR_FS_CATALOG;
		
		/*
		*	-> references the current protocol standard
		*/
		var $coo_filename			= 'sitemap1.xml';

		/*
		*	-> ping service
		*/
		var $coo_ping_service		= array(
										'Google', 
										'Yahoo!', 
										'Ask.com', 
										'Live Search'
										);

		/*
		*	-> host of ping service
		*/
		var $coo_ping_host			= array(
										'http://www.google.de', 
										'http://search.yahooapis.com', 
										'http://submissions.ask.com', 
										'http://webmaster.live.com'
										);
										
		/*
		*	-> path of ping service
		*/
		var $coo_ping_path			= array(
										'/webmasters/tools/ping?sitemap=', 
										'/SiteExplorerService/V1/ping?sitemap=', 
										'/ping?sitemap=', 
										'/ping.aspx?siteMap='
										);


		/*
		*	-> default constructor
		*/
		function GMSitemapXML($ping) 
		{
			$this->coo_language_id	= gm_get_conf('GM_SITEMAP_GOOGLE_LANGUAGE_ID');
			$this->coo_changefreq	= gm_get_conf('GM_SITEMAP_GOOGLE_CHANGEFREQ');
			$this->coo_priority		= gm_get_conf('GM_SITEMAP_GOOGLE_PRIORITY');

			$this->coo_request_uri	= HTTP_SERVER . DIR_WS_CATALOG . $this->coo_filename;
			$this->coo_seo_boost	= MainFactory::create_object('GMSEOBoost');
			$this->coo_ping			= $ping;

			return;
		}

		/*
		*	-> create sitemap
		*/
		function create() 
		{		
			$_xml  = '<?xml version="' . $this->coo_xml_version . '" encoding="' . $this->coo_xml_encoding . '"?>'	. "\n\t";

			$_xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">'									. "\n\n\t\t";
						
			$_xml .= $this->get_categories();			
			
			$_xml .= $this->get_content();

			$_xml .= "\n\t" . '</urlset>';

			$this->output($_xml);

			return TITLE_SITEMAP_CREATED . $this->coo_link_counter . TITLE_SITEMAP_CREATED2 . '<a href="' . HTTP_SERVER . DIR_WS_CATALOG . $this->coo_filename . '" target="_blank">' . $this->coo_filename. '</a><br /><br />' . $this->ping();
		}

		/*
		*	-> get categories
		*/
		function get_categories() 
		{			
			/*
			*	-> get cats 
			*/
			$gm_query = xtc_db_query("
										SELECT
											c.categories_id						AS id, 
											c.gm_priority						AS priority, 
											c.gm_changefreq						AS changefreq, 
											UNIX_TIMESTAMP(c.last_modified)		AS last_mod,
											UNIX_TIMESTAMP(c.date_added)		AS date_added,
											cd.categories_name					AS name,
											cd.gm_url_keywords					AS keyword
										FROM " .
											TABLE_CATEGORIES . " c 
										LEFT JOIN " .
											TABLE_CATEGORIES_DESCRIPTION . " cd 
										ON 
											c.categories_id = cd.categories_id 
										WHERE 
											cd.language_id = '" . (int) $this->coo_language_id . "'
										AND 
											c.parent_id = '0' 
										AND 
											c.categories_status = '1' 
										AND 
											c.gm_sitemap_entry = '1' " .
										$this->get_group_check('c') . "
										ORDER BY 
											c.sort_order, cd.categories_name
										");

			while($gm_array = xtc_db_fetch_array($gm_query)) 
			{				
				if($this->coo_seo_boost->boost_categories)
				{
					$this->coo_cat_path = $this->coo_seo_boost->get_boosted_category_url($gm_array['id'], (int)$this->coo_language_id);
					$gm_array['link']	= $this->coo_cat_path;
				}				
				
				$gm_sub_tree	= $this->get_categories_tree($gm_array['id']);
				$gm_prd			= $this->get_products($gm_array['id']);	

				$gm_help .= $this->add_url($gm_array);

				if(!empty($gm_sub_tree)) 
				{
					$gm_help .= $gm_sub_tree;
				}			
				
				if(!empty($gm_prd)) 
				{
					$gm_help .= $gm_prd;
				}			

				$gm_tree .= $gm_help;
				$gm_help = '';
			}	
			
			return $gm_tree;
		}

		/*
		*	-> get categories tree recursive
		*/
		function get_categories_tree($id) 
		{
			$gm_query = xtc_db_query("
										SELECT
											c.categories_id						AS id, 
											c.gm_priority						AS priority, 
											c.gm_changefreq						AS changefreq, 
											UNIX_TIMESTAMP(c.last_modified)		AS last_mod,
											UNIX_TIMESTAMP(c.date_added)		AS date_added,
											cd.categories_name					AS name,
											cd.gm_url_keywords					AS keyword
										FROM " .
											TABLE_CATEGORIES . " c 
										LEFT JOIN " .
											TABLE_CATEGORIES_DESCRIPTION . " cd 
										ON 
											c.categories_id = cd.categories_id 
										WHERE 
											cd.language_id = '" . (int) $this->coo_language_id . "'
										AND 
											c.parent_id = '" . $id . "' 
										AND 
											c.categories_status = '1' 
										AND 
											c.gm_sitemap_entry = '1' " .
										$this->get_group_check('c') . "
										ORDER BY 
											c.sort_order, cd.categories_name
										");
			
			while($gm_array = xtc_db_fetch_array($gm_query)) 
			{
				if($this->coo_seo_boost->boost_categories)
				{
					$gm_array['link'] = $this->coo_seo_boost->get_boosted_category_url($gm_array['id'], (int)$this->coo_language_id);
				}
				
				$gm_sub_tree = $this->get_categories_tree($gm_array['id']);				
				$gm_prd		 = $this->get_products($gm_array['id']);				


				$gm_help .= $this->add_url($gm_array);

				if(!empty($gm_sub_tree)) 
				{
					$gm_help .= $gm_sub_tree;
				}			
				
				if(!empty($gm_prd)) 
				{
					$gm_help .= $gm_prd;
				}			
				
				$gm_tree .= $gm_help;
				$gm_help = '';
				$this->coo_cat_sub_path = '';				
			}	
			return $gm_tree;
		}
		
		/*
		*	-> get articles
		*/
		function get_products($id) 
		{			
			$gm_query = xtc_db_query("
										SELECT
											p.products_id									AS id, 
											p.gm_priority									AS priority, 
											p.gm_changefreq									AS changefreq, 
											UNIX_TIMESTAMP(p.products_last_modified)		AS last_mod, 
											UNIX_TIMESTAMP(p.products_date_added)			AS date_added, 
											pd.products_name								AS name,
											pd.gm_url_keywords								AS keyword	
										FROM " .
											TABLE_PRODUCTS . " p 
										LEFT JOIN " .
											TABLE_PRODUCTS_DESCRIPTION . " pd 
										ON 
											p.products_id = pd.products_id 
										LEFT JOIN " .
											TABLE_PRODUCTS_TO_CATEGORIES . " ptc 
										ON 
											p.products_id = ptc.products_id
										WHERE 
											pd.language_id = '" . (int) $this->coo_language_id . "'
										AND 
											p.products_status = '1' 
										AND 
											ptc.categories_id = '" . $id . "'
										AND 
											p.gm_sitemap_entry = '1' " .
										$this->get_group_check('p') . "
										ORDER BY 
											p.products_sort, pd.products_name
										");

			if(xtc_db_num_rows($gm_query) > 0) 
			{
				while($gm_array = xtc_db_fetch_array($gm_query)) 
				{
					if($this->coo_seo_boost->boost_products) 
					{
						$gm_array['link'] = $this->coo_seo_boost->get_boosted_product_url($gm_array['id'], $gm_array['name'], (int)$this->coo_language_id);
					}					
					$products .= $this->add_url($gm_array, 'prd');												
				}

			} 
			else 
			{			
				$products = '';			
			}

			return $products;
		}

		/*
		*	-> get content
		*/
		function get_content() 
		{
			if($this->coo_seo_boost->boost_content) 
			{ 
				$group_query = "content_id AS id,";
			} 
			else 
			{
				$group_query = "content_group AS id,";
			}

			$gm_query = xtc_db_query(
									"SELECT
										gm_priority							AS priority, 
										gm_changefreq						AS changefreq, 
										" . $group_query . "
										content_title						AS heading,
										content_heading						AS name,
										gm_url_keywords						AS keyword,
										gm_link								AS link,
										UNIX_TIMESTAMP(gm_last_modified)	AS last_mod

									FROM " . 
										TABLE_CONTENT_MANAGER . "
									WHERE
										languages_id='" . (int) $this->coo_language_id . "'
									AND 
										file_flag!=4 " .
									$this->get_group_check('content') . "
									AND 
										content_status=1 
									AND 
										gm_sitemap_entry=1 
									ORDER BY 
										sort_order
									");

			while ($gm_array = xtc_db_fetch_array($gm_query)) 
			{				
				if(empty($gm_array['link']))
				{
					if($this->coo_seo_boost->boost_content) 
					{
						$gm_array['link'] = $this->coo_seo_boost->get_boosted_content_url($gm_array['id'], (int)$this->coo_language_id);
					}					
					$gm_tree .= $this->add_url($gm_array, 'content');
				}	
			}
			return $gm_tree;
		}

		/*
		*	-> create output
		*/
		function output($content) 
		{
			$fp = fopen($this->coo_path . $this->coo_filename, 'w');
			fwrite($fp, $content);
			fclose($fp);
			return;
		}

		/*
		* add url block
		*/
		function add_url($gm_array, $type='cat')
		{  			
			$url  = '<url>'																															. "\n\t\t\t";
	
			$url .= '<loc>' .		htmlspecialchars($this->get_link($gm_array['id'], $gm_array['name'], $type, $gm_array['link']))	. '</loc>'	. "\n\t\t\t";
			
			if(xtc_not_null($gm_array['last_mod']) || xtc_not_null($gm_array['date_added'])) 
			{
				$url .= '<lastmod>' .	$this->get_date($gm_array['last_mod'], $gm_array['date_added']) . '</lastmod>'								. "\n\t\t\t";
			}

			$url .= '<changefreq>' .$this->get_changefreq($gm_array['changefreq']) . '</changefreq>'												. "\n\t\t\t";

			$url .= '<priority>' .	$this->get_priority($gm_array['priority']) . '</priority>'														. "\n\t\t";
	
			$url .= '</url>'																														. "\n\t\t";
			
			$this->coo_link_counter++;

			return $url;
		}

		/*
		*	-> generate links
		*/
		function get_link($id, $name, $type, $link = '') 
		{   
			// -> handle cats
			if($type=='cat') 
			{
				if($this->coo_seo_boost->boost_categories) 
				{
					return gm_xtc_href_link($link);				
				} 
				else 
				{
					return gm_xtc_href_link('index.php', xtc_category_link($id, $name));
				}				

			// -> handle prds
			}
			elseif($type=='prd') 
			{
				if($this->coo_seo_boost->boost_products) 
				{
					return gm_xtc_href_link($link);
				} 
				else 
				{
					return gm_xtc_href_link('product_info.php', xtc_product_link($id, $name));
				}				

			// -> handle content
			} 
			elseif($type=='content') 
			{				
				if($this->coo_seo_boost->boost_content) 
				{
					return gm_xtc_href_link($link);
				} 
				else 
				{
					if (SEARCH_ENGINE_FRIENDLY_URLS == 'true') 
					{
						$SEF_parameter = '&content=' . xtc_cleanName($name);
					}
					return gm_xtc_href_link('shop_content.php', 'coID=' . $id . $SEF_parameter);
				}
			}	
		}

		/*
		*	-> get default changefreq, if standard is empty
		*/
		function get_changefreq($changefreq) 
		{
			if(empty($changefreq)) 
			{
				$changefreq = $this->coo_changefreq;
			}

			return $changefreq;
		}

		/*
		*	-> get default priority, if standard is empty
		*/
		function get_priority($priority) 
		{			
			if(empty($priority)) 
			{
				$priority = $this->coo_priority;
			}
			return $priority;
		}

		/*
		*	-> add group check
		*/
		function get_group_check($type) 
		{
			if 	(GROUP_CHECK == 'true') 
			{
				if($type=="content") 
				{
					$group_check = " AND group_ids LIKE '%c_1_group%'";
				} 
				else 
				{
					$group_check = " AND " . $type . ".group_permission_1=1 ";
				}

			} 
			else 
			{
				$group_check = "";			
			}	
			return $group_check;
		}

		/*
		*	-> format date
		*/
		function get_date($last_mod, $date_added) 
		{			
			if(!empty($last_mod))
			{
				return date("Y-m-d", $last_mod);
			} 
			elseif(!empty($date_added)) 
			{
				return date("Y-m-d", $date_added);
			} 
			else
			{
				return date("Y-m-d");
			}
		}

		/*
		*	-> ping
		*/
		function ping()
		{
			$ping = false;
			
			for($i=0; $i < count($this->coo_ping); $i++) 
			{								
				if(!empty($this->coo_ping[$i])) 
				{					
					$ping = true;
					if (function_exists('curl_init')) 
					{
						$message = '<div style="display:none;" id="ping_' . $i . '">' . $this->clean($this->use_curl($i))		. '</div>';
					}
					elseif(function_exists('fsockopen')) 
					{
						$message = '<div style="display:none;" id="ping_' . $i . '">' . $this->clean($this->use_fsockopen($i))	. '</div>';
					} 
					else 
					{
						$message =  TITLE_SITEMAP_FAILED;
					}

					$request		.= utf8_decode($message);
					$message		='';
					unset($message);
					$coo_ping_service	.=  ' <span class="gm_strong gm_pointer" onclick="gm_show_request(' . $i . ')" id="service_' . $i . '">' . $this->coo_ping_service[$i] . '</span>';				
				} 
			}			

			if($ping == true) 
			{
				return TITLE_SITEMAP_ANSWER . $coo_ping_service . TITLE_SITEMAP_ANSWER2 . '<br />' . $request;
			} 
			else 
			{
				return;		
			}			
		}

		/*
			-> using curl
		*/
		function use_curl($i) 
		{
			$ch = curl_init();

			curl_setopt($ch, CURLOPT_URL, $this->coo_ping_host[$i] . $this->coo_ping_path[$i] . $this->coo_request_uri);

			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);			

			$data = curl_exec($ch);

			curl_close($ch);

			return $data;
		}

		/*
			-> using fsockopen
		*/
		function use_fsockopen($i) 
		{
			$sock = fsockopen(str_replace('http://', '', $this->coo_ping_host[$i]), 80, $errno, $errstr, 5);
			fputs($sock, "GET " . $this->coo_ping_path[$i] . $this->coo_request_uri . " HTTP/1.1\r\n");
			fputs($sock, "Host: " . str_replace('http://', '',$this->coo_ping_host[$i]) . "\r\n");
			fputs($sock, "Connection: close\r\n\r\n");

			while(!feof($sock)) 
			{
				$data .= fgets($sock, 4096);
			}
			fclose($sock);
			return substr($data, strpos($data, '<'));
		}

		/*
			-> clean
		*/
		function clean($str) 
		{
			$search = array (
							'#<head[^>]*?>.*?</head>#si',
							'#<body[^>]*?>#si',
							'#<html[^>]*?>#si',
							'#<html[^>]*?>#si',
							'#<meta[^>]*?>#si',
							);

			$replace = array(
							' ',
							' ',
							' ',
							' ',
							' '
							);

			$restr = preg_replace($search, $replace, $str);			
			return $restr;
		}
	}